package  com.macllvm.whale.protocol;

import android.util.Log;
import java.util.Date;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ConcurrentMap;
import java.text.DateFormat;
import com.macllvm.whale.net.UDPClient;
import com.macllvm.whale.model.BuddyManager;
import com.macllvm.whale.model.MessageManager;
import com.macllvm.whale.model.TransferInManager;
import com.macllvm.whale.model.TransferOutManager;
import com.macllvm.whale.model.MessageManager;
import com.macllvm.whale.entity.Buddy;
import com.macllvm.whale.entity.Transfer;
import com.macllvm.whale.entity.Message;
import com.macllvm.whale.WhaleApplication;
import com.macllvm.whale.settings.SystemSettings;


public class ProtocolController   {

    private static final String TAG = "ProtocolController";
    private static final String BROADCAST_IP = "255.255.255.255";
    private String sessionIP = "";

    private UDPClient mUdpClient;
    private BuddyManager mBuddyManager;
    private MessageManager mMessageManager;
    private TransferInManager mTransferInManager;
    private TransferOutManager mTransferOutManager;
    private SystemSettings systemSettings;
    private static ProtocolController mController = new ProtocolController();
    public synchronized static ProtocolController getInstance() {
        return mController;
    }

    public  BuddyManager  getBuddyManager() {
        return mBuddyManager;
    }
    public  MessageManager  getMessageManager() { return mMessageManager; }
    public  TransferInManager  getTransferInManager() {
        return mTransferInManager;
    }
    public  TransferOutManager  getTransferOutManager() {
        return mTransferOutManager;
    }


    private ProtocolController() {
        mBuddyManager = new BuddyManager();
        mMessageManager = new MessageManager();
        mTransferInManager = new TransferInManager();
        mTransferOutManager = new TransferOutManager();
    }

    public  void setUDPClient(UDPClient client) {
        mUdpClient = client;
    }

    public void setSystemSettings(SystemSettings sysSettings){
        systemSettings = sysSettings;
    }

    public void setSessionIP(String ip) {
        sessionIP = ip;
    }

    public void  processPacket(final String ip, final String data){
        String[]  packetArgs = data.split(":");

        if(packetArgs.length >= 5) {
            int type = Integer.parseInt(packetArgs[4]);

            switch (ProtocolBase.GET_MODE(type)) {
                case ProtocolBase.IPMSG_BR_ENTRY: {
                    buddyLogin(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPMSG_BR_EXIT: {
                    buddyOffline(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPMSG_ANSENTRY: {
                    buddyOnline(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPMSG_BR_ABSENCE: {
                    buddyInfoChange(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPMSG_SENDMSG: {
                    buddySendMessage(ip, packetArgs);
                    WhaleApplication.mSoundPlayer.playNewMsg();
                }
                break;
                case ProtocolBase.IPMSG_RECVMSG: {
                    buddyRecviveMsg(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPTUX_ASKSHARED: {
                    buddyAskShareFile(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPTUX_SENDICON: {
                    buddySendIcon(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPTUX_SENDSIGN: {
                    buddySendSign(ip, packetArgs);
                }
                break;
                case ProtocolBase.IPTUX_SENDMSG: {
                    buddyBroadcast(ip, packetArgs);
                }
                break;
                default:
                    break;
            }
        }
    }

    private  void  addNewBuddy(final String ip,final String[] packets) {
        Buddy b = new Buddy();
        b.setUserName(packets[2]);
        b.setHostName(packets[3]);
        b.setNickName(packets[2]);
        b.setIP(ip);
        b.setState(Buddy.STATE_ONLINE);
        mBuddyManager.add(b);
        confirmOnline(ip);
    }

    public void  buddyLogin(final String ip,final String[] packets) {
        addNewBuddy(ip, packets);
    }

    public void  buddyOffline(final String ip,final String[] packets) {
        Buddy b = (Buddy)mBuddyManager.get(ip);
        if(null != b)
            b.setState(Buddy.STATE_OFFLINE);
    }

    public void  buddyOnline(final String ip,final String[] packets) {
        Buddy b = (Buddy)mBuddyManager.get(ip);
        if(null != b) {
            b.setState(Buddy.STATE_ONLINE);
        } else {
            addNewBuddy(ip, packets);
        }
    }

    public void  buddyInfoChange(final String ip,final String[] packets) {

    }

    public void  buddySendMessage(final String ip,final String[] packets) {
        int command =  Integer.valueOf(packets[4]);
        String packetNumber = packets[1];

        Buddy b = (Buddy)mBuddyManager.get(ip);
        if(null == b){
            return;
        }

        String msg = packets[5];
        char headChar = msg.charAt(0);
        if(headChar != '\0'){
            Date now = new Date();
            DateFormat df = DateFormat.getDateTimeInstance();
            String datetime = df.format(now);
            Message m = new Message(datetime, msg, Message.MESSAGE_IN);
            mMessageManager.add(ip, m);
            if(!( b.getIP().equals(sessionIP)) ){
                b.increateUnreadCount();
                mBuddyManager.refresh();
            }
        }

        if ( ProtocolBase.HAS_ATTACHED(command & ProtocolBase.IPMSG_SENDCHECKOPT) ) {
            sendReply(ip, packetNumber);
        }

        boolean ret =  ProtocolBase.HAS_ATTACHED(command & ProtocolBase.IPMSG_FILEATTACHOPT);
        if ( ret ) {

            if ( ProtocolBase.HAS_ATTACHED(command & ProtocolBase.IPTUX_SHAREDOPT)
                 && ProtocolBase.HAS_ATTACHED(command & ProtocolBase.IPTUX_PASSWDOPT)) {
                 return;     //filter share file request
            } else {
                recvFile(ip, packets);
            }
        }
    }

    public void buddyRecviveMsg(final String ip,final String[] packets) {

    }

    public void buddyAskShareFile(final String ip,final String[] packets) {

    }

    public void buddySendIcon(final String ip,final String[] packets) {

    }

    public void buddySendSign(final String ip,final String[] packets) {

    }

    public void buddyBroadcast(final String ip,final String[] packets) {

    }

    public  void broadcastOnline() {
        String nickName = (String)systemSettings.getSettingValue(systemSettings.KEY_NAME[2]);
        String data = PacketPackager.packagePacket(ProtocolBase.IPMSG_ABSENCEOPT | ProtocolBase.IPMSG_BR_ENTRY, nickName);
        mUdpClient.send(BROADCAST_IP, data);
    }

    public  void notifyOnlineToSomeBuddys(final String ip) {
        String nickName = (String)systemSettings.getSettingValue(systemSettings.KEY_NAME[2]);
        String data = PacketPackager.packagePacket(ProtocolBase.IPMSG_DIALUPOPT | ProtocolBase.IPMSG_ABSENCEOPT | ProtocolBase.IPMSG_BR_ENTRY,
                nickName);

        mUdpClient.send(ip, data);
    }

    public  void confirmOnline(final String ip) {
        String nickName = (String)systemSettings.getSettingValue(systemSettings.KEY_NAME[2]);
        String data = PacketPackager.packagePacket(ProtocolBase.IPMSG_ABSENCEOPT | ProtocolBase.IPMSG_ANSENTRY, nickName );
        mUdpClient.send(ip ,data);
    }

    public  void notifyOfflineToBuddy(final String ip) {
        String data = PacketPackager.packagePacket(ProtocolBase.IPMSG_DIALUPOPT | ProtocolBase.IPMSG_BR_EXIT, null);
        mUdpClient.send(ip, data);
    }

    public  void notifyInfoChangeToBuddy(final String ip) {

    }

    public  void notifyOnlineToOne(final String ip) {

    }

    public  void sendMessage(final String ip,final String msg) {
        Date now = new Date();
        DateFormat df = DateFormat.getDateTimeInstance(); //默认语言（汉语）下的默认风格（MEDIUM风格，比如：2008-6-16 20:54:53）
        String datetime = df.format(now);
        Message m = new Message(datetime, msg, Message.MESSAGE_OUT );
        mMessageManager.add(ip, m);

        String data = PacketPackager.packagePacket(ProtocolBase.IPMSG_SENDCHECKOPT | ProtocolBase.IPMSG_SENDMSG, msg);
        mUdpClient.send(ip, data);
    }

    public  void sendReply(final String ip, final String packetNumber) {
        String data = PacketPackager.packagePacket(ProtocolBase.IPMSG_SENDCHECKOPT | ProtocolBase.IPMSG_RECVMSG, packetNumber);
        mUdpClient.send(ip, data);
    }

    public  void sendGroupMessage() {

    }

    public  void sendUnitMessage() {

        return;
    }

    public  boolean requestFileData() {

        return true;
    }

    public  boolean requestDirData() {

        return true;
    }

    public  void requestShareFile(final String ip, int optType, String attachedData) {

    }

    public  void sendFileData(final String ip, int optType, String attachedData) {

    }

    public  void sendMyAvator(final String ip) {

    }

    public  void sendMySignature(final String ip, String sign) {

    }

    public  void sendFileDataUseTCP(final String ip, int optType) {

    }

    public  void feedBackError() {

    }

    public  void  recvFile(final String ip, final String[] packets){
        int packgetNumber = Integer.parseInt(packets[1]);
        int attachedFileArgs = 5;
        int count = (packets.length - attachedFileArgs) / attachedFileArgs;
        String fileList = "";

        for(int  i= 0 ;i < count; i++){
            Transfer transfer = new Transfer();
            int index = attachedFileArgs * i + attachedFileArgs;
            String idSection = packets[index];

            if(idSection.charAt(0) == '\0') {
                idSection = idSection.replace("\0", "");
            }
            if((int)idSection.charAt(0) == 7){
                idSection = idSection.substring(1, idSection.length());
            }

            transfer.fileId = Integer.parseInt(idSection);
            transfer.ip = ip;
            transfer.state = Transfer.STATE_READY;
            transfer.transferType = Transfer.TYPE_RECV;
            transfer.fileAttr = Integer.parseInt(packets[index + 4]);
            transfer.fileNumber =  Integer.parseInt(packets[1]);
            transfer.filePath = SystemSettings.DOWNLOAD +"/"+packets[index + 1];
            transfer.fileCreateTime = Long.parseLong(packets[index + 3], 16);
            transfer.fileSize = Long.parseLong(packets[index + 2], 16);
            transfer.transferType = Transfer.TYPE_RECV;

            mTransferInManager.add(transfer);

            if(i > 0)
                fileList += "\n";
            fileList += packets[index + 1];

        }

        Date now = new Date();
        DateFormat df = DateFormat.getDateTimeInstance();
        String datetime = df.format(now);
        Message m = new Message(datetime, fileList, Message.MESSAGE_TIP_IN);
        mMessageManager.add(ip, m);
    }

    public  void  sendFileInfo(final String ip, String fileInfo){
        int optType = 0;
        String data = PacketPackager.packagePacket( optType | ProtocolBase.IPMSG_FILEATTACHOPT | ProtocolBase.IPMSG_SENDMSG, fileInfo );
        mUdpClient.send(ip, data);
    }


    public  void  handleSendClient(SocketChannel channel) {
        mTransferOutManager.startSendTask(channel);
    }
}
